﻿using FreeRedis;
using Microsoft.Extensions.Localization;
using System.Collections.Concurrent;
using System.Runtime.CompilerServices;
using Volo.Abp.Localization;

namespace CTP.CRM.Core.Localization
{
    public class CTPRedisLocalizationResource : ILocalizationResourceContributor, IDisposable
    {
        private readonly RedisResourceOptions _options;

        private readonly RedisClient _redisClient;

        private readonly ConcurrentDictionary<string, string> _languages = new ConcurrentDictionary<string, string>();

        private readonly string _keyPrefix;

        private bool disposedValue;

        //
        // 摘要:
        //     属于动态语言集
        public bool IsDynamic => true;

        internal CTPRedisLocalizationResource(RedisClient redisClient, RedisResourceOptions options)
        {
            _options = options;
            _keyPrefix = options.KeyPrefix + ":" + options.SystemName;
            _redisClient = redisClient;
            _redisClient.UseClientSideCaching(new ClientSideCachingOptions
            {
                Capacity = 20,
                KeyFilter = (string key) => key.StartsWith(_keyPrefix),
                CheckExpired = (string key, DateTime dt) => DateTime.Now.Subtract(dt) > TimeSpan.FromHours(5.0)
            });
        }

        //
        // 摘要:
        //     填充
        //
        // 参数:
        //   cultureName:
        //
        //   dictionary:
        public void Fill(string cultureName, Dictionary<string, LocalizedString> dictionary)
        {
            Dictionary<string, string> dictionary2 = _redisClient.HGetAll(_keyPrefix + ":" + cultureName);
            foreach (KeyValuePair<string, string> item in dictionary2)
            {
                dictionary.Add(item.Key, new LocalizedString(item.Key, item.Value));
            }
        }

        //
        // 摘要:
        //     填充
        //
        // 参数:
        //   cultureName:
        //
        //   dictionary:
        public async Task FillAsync(string cultureName, Dictionary<string, LocalizedString> dictionary)
        {
            foreach (KeyValuePair<string, string> item in await _redisClient.HGetAllAsync(_keyPrefix + ":" + cultureName))
            {
                dictionary.Add(item.Key, new LocalizedString(item.Key, item.Value));
            }
        }

        //
        // 摘要:
        //     获取本地化字符串
        //
        // 参数:
        //   cultureName:
        //     语言名称
        //
        //   name:
        //     key
        public LocalizedString GetOrNull(string cultureName, string name)
        {
            string languageKey = GetLanguageKey(cultureName);
            string value = _redisClient.HGet(languageKey, name);
            if (!string.IsNullOrEmpty(value))
            {
                return new LocalizedString(name, value);
            }

            return new LocalizedString(name, name, resourceNotFound: true);
        }

        //
        // 摘要:
        //     支持的语言
        public async Task<IEnumerable<string>> GetSupportedCulturesAsync()
        {
            await Task.CompletedTask;
            return _languages.Keys;
        }

        //
        // 摘要:
        //     初始化
        //
        // 参数:
        //   context:
        public void Initialize(LocalizationResourceInitializationContext context)
        {
            _languages.Clear();
            List<string> list = new List<string>();
            string[] array = _redisClient.Keys(_keyPrefix + ":*");
            if (array == null || array.Length == 0)
            {
                return;
            }

            list.AddRange(array);
            foreach (string item in list)
            {
                string text = item.Split(":").LastOrDefault();
                if (text != null)
                {
                    _languages.TryAdd(text, item);
                    _redisClient.HGetAll(item);
                }
            }
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private string? GetLanguageKey(string cultureName)
        {
            return _keyPrefix + ":" + cultureName;
        }

        //
        // 参数:
        //   disposing:
        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                }

                _redisClient.Dispose();
                disposedValue = true;
            }
        }

        public void Dispose()
        {
            Dispose(disposing: true);
            GC.SuppressFinalize(this);
        }
    }
}
